package dao;

import java.security.*;
import java.sql.*;
import java.util.*;

import model.*;

public class UserManager
{

    public static String encodePassword(String password) throws Exception
    {
	MessageDigest digest = MessageDigest.getInstance("SHA-256");
	digest.reset();
	byte[] input = digest.digest(password.getBytes("UTF-8"));
	StringBuilder builder = new StringBuilder();
	for (int i = 0; i < input.length; i++)
	{
	    builder.append(Integer.toHexString(0xFF & input[i]));
	}
	return builder.toString();
    }

    public static boolean registerUser(User user)
    {
	try
	{
	    Connection conn = ConnectionManager.getInstance().getConnection();
	    PreparedStatement ps = conn
		    .prepareStatement("INSERT INTO Users VALUES (?,?,?,?,?,?,?,?)");
	    ps.setString(1, user.getUsername());
	    ps.setString(2, user.getName());
	    ps.setString(3, user.getSurname());
	    ps.setString(4, encodePassword(user.getPassword1()));
	    ps.setString(5, user.getEmail());
	    ps.setString(6, user.getWorkplace());
	    ps.setInt(7, user.isAdmin() ? 1 : 0);
	    ps.setInt(8, user.getMaxItems());
	    int updated = ps.executeUpdate();
	    ConnectionManager.getInstance().returnConnection(conn);
	    return updated > 0;
	}
	catch (Exception e)
	{
	    return false;
	}
    }

    public static boolean updateUser(User user)
    {
	try
	{
	    Connection conn = ConnectionManager.getInstance().getConnection();
	    PreparedStatement ps = conn
		    .prepareStatement("UPDATE Users SET name=?,surname=?,password=?,email=?,workplace=?,type=?,max_items=? WHERE username=?");
	    ps.setString(1, user.getName());
	    ps.setString(2, user.getSurname());
	    ps.setString(3, encodePassword(user.getPassword1()));
	    ps.setString(4, user.getEmail());
	    ps.setString(5, user.getWorkplace());
	    ps.setInt(6, user.isAdmin() ? 1 : 0);
	    ps.setInt(7, user.getMaxItems());
	    ps.setString(8, user.getUsername());
	    int updated = ps.executeUpdate();
	    ConnectionManager.getInstance().returnConnection(conn);
	    return updated > 0;
	}
	catch (Exception e)
	{
	    return false;
	}
    }

    public static boolean containsUser(String username)
    {
	int count = 0;
	try
	{
	    Connection conn = ConnectionManager.getInstance().getConnection();
	    PreparedStatement ps = conn
		    .prepareStatement("SELECT * FROM Users WHERE username=?");
	    ps.setString(1, username);
	    ResultSet rs = ps.executeQuery();
	    while (rs.next())
	    {
		count++;
	    }
	    ConnectionManager.getInstance().returnConnection(conn);
	}
	catch (Exception e)
	{
	}
	return count > 0;
    }

    public static User getUser(String username, String password)
    {
	User user = null;
	try
	{
	    Connection conn = ConnectionManager.getInstance().getConnection();
	    PreparedStatement ps = conn
		    .prepareStatement("SELECT * FROM Users WHERE username=? AND password=?");
	    ps.setString(1, username);
	    ps.setString(2, encodePassword(password));
	    ResultSet rs = ps.executeQuery();
	    while (rs.next())
	    {
		user = new User();
		user.setUsername(username);
		user.setName(rs.getString("name"));
		user.setSurname(rs.getString("surname"));
		user.setEmail(rs.getString("email"));
		user.setWorkplace(rs.getString("workplace"));
		user.setAdmin(rs.getInt("type") == 1);
		user.setMaxItems(rs.getInt("max_items"));
	    }
	    ConnectionManager.getInstance().returnConnection(conn);
	}
	catch (Exception e)
	{
	}
	return user;
    }

    public static User getUser(String username)
    {
	User user = null;
	try
	{
	    Connection conn = ConnectionManager.getInstance().getConnection();
	    PreparedStatement ps = conn
		    .prepareStatement("SELECT * FROM Users WHERE username=?");
	    ps.setString(1, username);
	    ResultSet rs = ps.executeQuery();
	    while (rs.next())
	    {
		user = new User();
		user.setUsername(username);
		user.setName(rs.getString("name"));
		user.setSurname(rs.getString("surname"));
		user.setEmail(rs.getString("email"));
		user.setWorkplace(rs.getString("workplace"));
		user.setAdmin(rs.getInt("type") == 1);
		user.setMaxItems(rs.getInt("max_items"));
	    }
	    ConnectionManager.getInstance().returnConnection(conn);
	}
	catch (Exception e)
	{
	}
	return user;
    }

    public static List<String> getAllUsernames()
    {
	List<String> result = new ArrayList<String>();
	try
	{
	    Connection conn = ConnectionManager.getInstance().getConnection();
	    PreparedStatement ps = conn
		    .prepareStatement("SELECT username FROM Users");
	    ResultSet rs = ps.executeQuery();
	    while (rs.next())
	    {
		result.add(rs.getString("username"));
	    }
	    ConnectionManager.getInstance().returnConnection(conn);
	}
	catch (Exception e)
	{
	}
	return result;
    }

    public static List<User> fetchAllUsers()
    {
	List<User> users = new ArrayList<User>();
	try
	{
	    Connection conn = ConnectionManager.getInstance().getConnection();
	    PreparedStatement ps = conn.prepareStatement("SELECT * FROM Users");
	    ResultSet rs = ps.executeQuery();
	    while (rs.next())
	    {
		User user = new User();
		user.setUsername(rs.getString("username"));
		user.setName(rs.getString("name"));
		user.setSurname(rs.getString("surname"));
		user.setEmail(rs.getString("email"));
		user.setWorkplace(rs.getString("workplace"));
		user.setAdmin(rs.getInt("type") == 1);
		user.setMaxItems(rs.getInt("max_items"));
		users.add(user);
	    }
	    ConnectionManager.getInstance().returnConnection(conn);
	}
	catch (Exception e)
	{
	}
	return users;
    }
}